﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using NetFrame.Net.TCP.Sock.Asynchronous;

namespace KD.Sms.Card
{
    internal class Stm32Main
    {
        private static string _StmIP = string.Empty;
        private static int _StmPort = 5000;
        List<CardInfo> _listValue;
        public Reader ReaderControllor = new Reader();
        private AsyncSocketState currentclient;
        int _iReadCount = 0;
        bool _bReadComplete = false;
        Hashtable _hasTids = new Hashtable();
        /// <summary>
        /// 本类的唯一实例
        /// </summary>
        private static Stm32Main OWNER = null;
        private Thread _thMain = null;

        /// <summary>
        /// 获取类的唯一实例
        /// </summary>
        /// <returns></returns>
        public static Stm32Main Instance
        {
            get
            {
                if (Stm32Main.OWNER == null)
                {
                    Stm32Main.OWNER = new Stm32Main();
                }
                return Stm32Main.OWNER;
            }
        }

        /// <summary>
        /// 读卡
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        public void DoRead(string ip, int port, bool justread)
        {
            _StmIP = ip;
            _StmPort = port;
            if (_thMain != null)
            {
                _thMain.Abort();
                System.Threading.Thread.Sleep(200);
            }
            _thMain = new Thread(new ParameterizedThreadStart(DoReadStm32)) { IsBackground = true };
            _thMain.Start(justread);
        }

        /// <summary>
        /// 
        /// </summary>
        private void DoReadStm32(object readtype)
        {
            _hasTids = new Hashtable();
            Entity.StmResult model = new Entity.StmResult(false, null, null);
            try
            {
                if (NetJudger.DoJudge(_StmIP))
                {
                    _listValue = new List<CardInfo>();
                    ReaderControllor = new Reader();
                    model.E_ReadBegin = DateTime.Now;
                    model.E_JustRead = Convert.ToBoolean(readtype);
                    ReaderControllor.cmd.MultiEPC_Event += DoAnalysisTID;
                    if (ReaderControllor.ConnectToServer_V2(_StmIP, _StmPort, true))
                    {
                        currentclient = null;
                        List<AsyncSocketState> Clients;
                        for (int i = 0; i < 50; i++)
                        {
                            Clients = ReaderControllor.GetClientInfo();
                            if (Clients != null && Clients.Count > 0)
                            {
                                currentclient = Clients[0];
                                break;
                            }
                            System.Threading.Thread.Sleep(100);
                        }
                        if (currentclient != null)
                        {
                            string result = ReaderControllor.StartMultiEPC(currentclient);
                            if (result == "0")
                            {
                                _iReadCount = 0;
                                _bReadComplete = false;
                                for (int i = 0; i < 180; i++)
                                {
                                    if (_bReadComplete)
                                    {
                                        model.E_Success = true;
                                        model.E_ReadEnd = DateTime.Now;
                                        break;
                                    }
                                    else
                                        System.Threading.Thread.Sleep(50);
                                }
                                ReaderControllor.StopMultiEPC(currentclient);
                                System.Threading.Thread.Sleep(200);
                                ReaderControllor.DisConnectToServer_V2(currentclient);
                                model.E_Cards = _listValue;
                            }
                            else
                                model.E_Desc = "启动读卡失败";
                        }
                        else
                            model.E_Desc = "无法读卡器句柄";
                    }
                    else
                        model.E_Desc = "在与读卡器建立连接的过程中出错";
                }
                else
                    model.E_Desc = string.Format("读卡器地址[{0}]网络中断", _StmIP);
            }
            catch (Exception ex)
            {
                model.E_Desc = "样桶读卡出现未知异常!详见日志!";
                Log.LogHelper.DoWriteLogTypeClass(Log.LogType.Program, System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName, "样桶读卡出现未知异常!详见日志!");
                Log.LogHelper.DoWriteLogTypeClass(Log.LogType.Program, System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName, ex.ToString());
                Log.LogHelper.DoWriteLogTypeClass(Log.LogType.Error, System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName, "样桶读卡出现未知异常!详见日志!");
                Log.LogHelper.DoWriteLogTypeClass(Log.LogType.Error, System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName, ex.ToString());
            }
            //通过异步事件的方式返回结果
            ActionCenter.Action.Instance.DoReadCardStm32(model);
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DoAnalysisTID(object sender, Command.ShowEPCEventArgs e)
        {
            try
            {
                if (!_bReadComplete)
                {
                    string[] result = (e.CommandRespond + ",0").Split(',');
                    if (result.Length > 15)
                    {
                        _iReadCount++;
                        lock (_listValue)
                        {
                            var tid = result[13].ToUpper().Replace("-", "").Substring(8, 16);
                            if (_listValue.Find(c => c.E_Tid == tid) == null)
                            {
                                _listValue.Add(new CardInfo(tid));
                            }
                            else
                            {
                                _listValue.Find(c => c.E_Tid == tid).E_Count += 1;
                            }
                        }
                        if (_iReadCount >= 25)
                        {
                            _bReadComplete = true;
                        }
                    }
                }
            }
            catch (Exception ex)
            { }
        }
    }

    public class CardInfo
    {
        public CardInfo(string tid)
        {
            E_Tid = tid;
            E_Count = 0;
        }
        public string E_Tid { set; get; }
        public int E_Count { set; get; }
    }
}
